bitkeeper revision 1.1236.12.4 (422d7a50g-lmMcSI2gKt0v9vRXTjYQ)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 8 Mar 2005 10:11:28 +0000 (10:11 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 8 Mar 2005 10:11:28 +0000 (10:11 +0000)
Clean up timer upcalls to guest kernel. Only send an upcall when
timestamp info actually changes.
Signed-off-by: Keir Fraser <keir.fraser@cl.cam.ac.uk>
xen/arch/ia64/domain.c
xen/arch/ia64/patch/linux-2.6.7/time.c
xen/arch/x86/domain_build.c
xen/arch/x86/time.c
xen/common/domain.c
xen/common/schedule.c
xen/include/xen/time.h

index 69b0774a8098fb96497b95add35539adca45a4c5..c5f1533f88be729f1e8ecb029a6a0cc859f8f253 100644 (file)
@@ -555,9 +555,6 @@ int construct_dom0(struct domain *d,
 #if 0
     strcpy(d->name,"Domain0");
 #endif
-    /* Set up shared-info area. */
-    update_dom_time(d);
-    d->shared_info->domain_time = 0;
 
        // prepare domain0 pagetable (maps METAphysical to physical)
        // following is roughly mm_init() in linux/kernel/fork.c
index 5ec93f8bc27ec7b050bcd923e28a9bc4eaef74a1..a21c0465c81b05cc039b207ea29808058402e7da 100644 (file)
@@ -71,7 +71,7 @@
 +    return now; 
 +}
 +
-+void update_dom_time(struct domain *d)
++void update_dom_time(struct exec_domain *ed)
 +{
 +// FIXME: implement this?
 +      printf("update_dom_time: called, not implemented, skipping\n");
index c8e378eb0066d33bd29cf4a1a98ec20401a3ccb7..d2de1138cd57eef798153db85dfd50a262d9cbd1 100644 (file)
@@ -406,9 +406,6 @@ int construct_dom0(struct domain *d,
 
 #endif /* __x86_64__ */
 
-    /* Set up shared-info area. */
-    update_dom_time(d);
-    d->shared_info->domain_time = 0;
     /* Mask all upcalls... */
     for ( i = 0; i < MAX_VIRT_CPUS; i++ )
         d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
index e4d28aa54d03074986f1583e32205f894a2bf739..52a086a2398e99128a9232e7de162691188de2f7 100644 (file)
@@ -13,7 +13,9 @@
  *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
  */
 
+#include <xen/config.h>
 #include <xen/errno.h>
+#include <xen/event.h>
 #include <xen/sched.h>
 #include <xen/lib.h>
 #include <xen/config.h>
@@ -273,15 +275,20 @@ s_time_t get_s_time(void)
 }
 
 
-void update_dom_time(struct domain *d)
+void update_dom_time(struct exec_domain *ed)
 {
+    struct domain *d  = ed->domain;
     shared_info_t *si = d->shared_info;
     unsigned long flags;
 
-    read_lock_irqsave(&time_lock, flags);
+    if ( d->last_propagated_timestamp == full_tsc_irq )
+        return;
 
+    read_lock_irqsave(&time_lock, flags);
     spin_lock(&d->time_lock);
 
+    d->last_propagated_timestamp = full_tsc_irq;
+
     si->time_version1++;
     wmb();
 
@@ -295,8 +302,9 @@ void update_dom_time(struct domain *d)
     si->time_version2++;
 
     spin_unlock(&d->time_lock);
-
     read_unlock_irqrestore(&time_lock, flags);
+
+    send_guest_virq(ed, VIRQ_TIMER);
 }
 
 
@@ -322,7 +330,9 @@ void do_settime(unsigned long secs, unsigned long usecs, u64 system_time_base)
 
     write_unlock_irq(&time_lock);
 
-    update_dom_time(current->domain);
+    /* Others will pick up the change at the next tick. */
+    current->domain->last_propagated_timestamp = 0; /* force propagation */
+    update_dom_time(current);
 }
 
 
index c80b9b157ffbf1537126c69f014c9f70b4c3f718..50e3b85405cf7be9c15818dc87ed2802a56a08be 100644 (file)
@@ -283,9 +283,6 @@ int final_setup_guest(struct domain *p, dom0_builddomain_t *builddomain)
     if ( (rc = arch_final_setup_guest(p->exec_domain[0],c)) != 0 )
         goto out;
 
-    /* Set up the shared info structure. */
-    update_dom_time(p);
-
     set_bit(DF_CONSTRUCTED, &p->d_flags);
 
  out:    
@@ -339,9 +336,6 @@ long do_boot_vcpu(unsigned long vcpu, full_execution_context_t *ctxt)
         goto out;
     }
 
-    /* Set up the shared info structure. */
-    update_dom_time(d);
-
     /* domain_unpause_by_systemcontroller */
     if ( test_and_clear_bit(EDF_CTRLPAUSE, &ed->ed_flags) )
         domain_wake(ed);
index eb2ae6fcacbee9e3411e9fa343f787994fda63a0..a0cd4303c28ca223c31b42d3c498df8b8299d38f 100644 (file)
@@ -414,10 +414,6 @@ void __enter_scheduler(void)
 
     spin_unlock_irq(&schedule_data[cpu].schedule_lock);
 
-    /* Ensure that the domain has an up-to-date time base. */
-    if ( !is_idle_task(next->domain) )
-        update_dom_time(next->domain);
-
     if ( unlikely(prev == next) )
         return;
     
@@ -460,10 +456,10 @@ void __enter_scheduler(void)
      */
     clear_bit(EDF_RUNNING, &prev->ed_flags);
 
-    /* Mark a timer event for the newly-scheduled domain. */
+    /* Ensure that the domain has an up-to-date time base. */
     if ( !is_idle_task(next->domain) )
-        send_guest_virq(next, VIRQ_TIMER);
-    
+        update_dom_time(next);
+
     schedule_tail(next);
 
     BUG();
@@ -500,10 +496,7 @@ static void t_timer_fn(unsigned long unused)
     TRACE_0D(TRC_SCHED_T_TIMER_FN);
 
     if ( !is_idle_task(ed->domain) )
-    {
-        update_dom_time(ed->domain);
-        send_guest_virq(ed, VIRQ_TIMER);
-    }
+        update_dom_time(ed);
 
     t_timer[ed->processor].expires = NOW() + MILLISECS(10);
     add_ac_timer(&t_timer[ed->processor]);
@@ -515,8 +508,7 @@ static void dom_timer_fn(unsigned long data)
     struct exec_domain *ed = (struct exec_domain *)data;
 
     TRACE_0D(TRC_SCHED_DOM_TIMER_FN);
-    update_dom_time(ed->domain);
-    send_guest_virq(ed, VIRQ_TIMER);
+    update_dom_time(ed);
 }
 
 /* Initialise the data structures. */
index 8bfcaed79e37a2ac84d8c1a000a723d1545d4b5e..1e7ba6657ebf0e26feece34cf11f935014ca90d8 100644 (file)
@@ -54,7 +54,7 @@ s_time_t get_s_time(void);
 #define MILLISECS(_ms)  (((s_time_t)(_ms)) * 1000000ULL )
 #define MICROSECS(_us)  (((s_time_t)(_us)) * 1000ULL )
 
-extern void update_dom_time(struct domain *d);
+extern void update_dom_time(struct exec_domain *ed);
 extern void do_settime(unsigned long secs, unsigned long usecs, 
                        u64 system_time_base);